<?php
class subject {
	private $root = null;
	private $index = null;

	public function __construct() {
		$this->root = ROOT_PATH . 'data' . DIRECTORY_SEPARATOR . 'subject' . DIRECTORY_SEPARATOR;
		$this->index = 'index.dat';
	}

	/**
	 * 添加项目
	 *
	 */
	public function add($name, $dir, $module) {
		if(!$name || !$dir || !$module) {
			return false;
		}

		if($this->isExist($name, $module)) {
			return false;
		}

		//组合数据
		$data = array(
			'name'   => $name,
			'dir'    => $dir,
			'module' => $module,
		);

		$res = $this->writeSubject($data);
		return $res;
	}

	/**
	 * 删除项目
	 *
	 */
	public function remove($key) {
		if(!$key) {
			return false;
		}

		$subjects = $this->getSubjects();
		foreach($subjects as $k => $val) {
			if($val['key'] == $key) {
				//删除项目信息
				$dir = $val['dir'];
				$folder = $this->root . $dir . DIRECTORY_SEPARATOR;
				delDir($folder);

				unset($subjects[$k]);
			}
		}

		$subjects = array_values($subjects);
		$data     = json_encode($subjects);
		$tmp      = file_put_contents($this->getIndex(), $data);

		if(!$tmp) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * 项目是不是已经存在了 
	 *
	 */
	public function isExist($name, $module) {
		//读取已经存在的项目
		$subjects = $this->getSubjects();
		foreach($subjects as $subject) {
			if($subject['name'] == $name || $subject['module'] == $module) {
				return true;
			}
		}

		return false;
	}

	/**
	 *  获取所有项目的大致信息 
	 *
	 */
	public function getSubjects() {
		$index = $this->getIndex();
		$tmp = file_get_contents($index);
		$content = json_decode($tmp);
		if(is_null($content)) {
			return array();
		} else {
			return object2array($content);
		}
	}

	/**
	 * 通过key值获取项目数据 
	 * @param getDefault 如果key值没有对应数据，就获取第一个
	 *
	 */
	public function getSubjectByKey($key, $getDefault = false) {
		//获取所有的数据
		$subjects = $this->getSubjects();
		$res      = false;

		if($key) {
			foreach ($subjects as $value) {
				if($value['key'] == $key) {
					$res = $value;
					break;
				}
			}
		}

		if($res == false && $getDefault) {
			$res = isset($subjects[0]) ? $subjects[0] : false;
		}

		return $res;
	}

	/**
	 * 写入项目数据 
	 *
	 */
	public function writeSubject($subjectArr) {
		if(!is_array($subjectArr) || !isset($subjectArr['dir']) || !$subjectArr['dir']) {
			return false;
		}

		$dir = $subjectArr['dir'];
		$subjects = $this->getSubjects();

		$key = md5(serialize($subjectArr));
		$subjectArr['key'] = $key;

		$tmp = array_unshift($subjects, $subjectArr);
		if(!$tmp) {
			return false;
		}

		$data = json_encode($subjects);
		$tmp = file_put_contents($this->getIndex(), $data);

		if(!$tmp) {
			return false;
		}

		//添加项目数据目录
		$folder = $this->root . $dir . DIRECTORY_SEPARATOR;
		dmkdir($folder);

		return true;
	}

	/**
	 * 获取项目根文件 
	 *
	 */
	public function getIndex() {
		$file = $this->root . $this->index;
		if(!file_exists($file)) {
			dmkdir($this->root);
			@touch($file);
		}

		return $file;
	}

	/**
	 * 获取存放项目同步信息的根目录 
	 *
	 */
	public function getRootInfo($dir) {
		if(!$dir) {
			return array();
		}

		$res = array(
			'log_file'  => $this->root . $dir . DIRECTORY_SEPARATOR . 'file_log.txt',
			'from_file' => $this->root . $dir . DIRECTORY_SEPARATOR . 'files_from.txt',
		);
		
		return $res;
	}

	/**
	 * 获取上次同步的文件 
	 *
	 */
	public function getSyncFiles($dir) {
		$info = $this->getRootInfo($dir);
		$res  = '';
		if($info) {
			$file = $info['from_file'];
			if(file_exists($file)) {
				$res = file_get_contents($file);
			}
		}

		//返回
		return $res;
	}

	/**
	 * 获取存放项目同步信息的根目录 
	 *
	 */
	public function getRoot() {
		return $this->root;
	}

	/**
	 * 执行同步命令
	 * @param dir 项目的目录
	 * @param module rsync模块
	 * @param codes 需要同步的代码
	 * @param simulate 是不是模拟同步
	 * 
	 * @return 同步输出的内容
	 * 	-1:参数错误 -2：配置有问题 -3：同步文件写入出错 false:同步出错 
	 */
	public function runCmd($dir, $module, $codes, $simulate = true) {
		if(!$dir || !$module || !$codes) {
			return -1;
		}

		global $_G;
		$projectInfo = $_G['config']['project'];

		$real_sync     = $projectInfo['real_sync'];
		$simulate_sync = $projectInfo['simulate_sync'];
		$auth_user     = $projectInfo['auth_user'];
		$pass_file     = $projectInfo['pass_file'];

		$log_files     = $projectInfo['log_files'];
		$files_from    = $projectInfo['files_from'];

		$remote_ip     = $projectInfo['remote_ip'];
		$pre_local     = $projectInfo['pre_local'];
		
		if(!$real_sync || !$simulate_sync || !$auth_user || !$remote_ip || !$pre_local || !$pass_file) {
			return -2;
		}

		$cmd = '';
		if($simulate) {
			$cmd .= $simulate_sync;
		} else {
			$cmd .= $real_sync;
		}

		//将数据写入文件
		$info     = $this->getRootInfo($dir);
		$fromFile = $info['from_file'];
		$logFile  = $info['log_file'];
		$res      = file_put_contents($fromFile, $codes);
		if(!$res) {
			return -3;
		}

		//组合命令
		$cmd .= ' --password-file=' . $pass_file;
		$cmd .= ' --log-file=' . $logFile;
		$cmd .= ' --files-from=' . $fromFile;

		//项目实际目录
		$localFolder = $pre_local . $dir . '/';
		$cmd         .= ' ' . $localFolder;
		$cmd         .= ' ' . $auth_user . '@' . $remote_ip . '::' . $module;

		//执行命令
		$res = shell_exec($cmd);
		if(!$res) {
			return false;
		} else {
			return nl2br($res);
		}
	}
}